package com.rojored.core
{

import com.rojored.core.cacheClasses.DeleteStatus;
import org.flexunit.Assert;

/**
 *  Tests basic cache functionality.
 */
public class CacheTest
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor
     */
    public function CacheTest()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private var cache:ICache;

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    [Before]

    /**
     *   Resets the cache instance.
     */
    public function resetCache():void
    {
        cache = new Cache();
    }

    [Test(description="Cache sets and gets value associated with a key.")]

    /**
     *  Test that the cache sets and gets a values associated with a key.
     */
    public function testCacheSet():void
    {
        var key:String = "key";
        var value:String = "value";
        Assert.assertEquals(null, cache.get(key));
        cache.set("key", "value");
        Assert.assertEquals(value, cache.get(key));
    }

    [Test(description="Test that cached items are not defined after a flush-all")]

    /**
     *  Test that cached items are not defined after a flush-all
     */
    public function testCacheFlush():void
    {
        var key:String = "key";
        var value:String = "value";
        cache.set("key", "value");
        cache.flushAll();
        Assert.assertEquals(null, cache.get(key));
    }

     [Test(description="Test remove status returned for successful item deletion from cache.")]

    /**
     *  Test remove status returned for successful item deletion from cache.
     */
    public function testSuccessfulDeleteStatus():void
    {
        var key:String = "key";
        var value:String = "value";
        cache.set(key, value);
        Assert.assertEquals(DeleteStatus.DELETE_SUCCESSFUL, cache.deleteItem(key));
    }

    [Test(description="Test that an deleteItem request for a missing item returns DELETE_ITEM_MISSING")]

    /**
     *  Test that an deleteItem request for a missing item returns
     *  DeleteStatus.DELETE_ITEM_MISSING
     */
    public function testDeleteItemMissingStatus():void
    {
        Assert.assertEquals(DeleteStatus.DELETE_ITEM_MISSING,
            cache.deleteItem("missing key"));
    }

    [Test(description=" Test that a false cached item won't be treated as missing.")]

    /**
     *   Test false cached value won't be trated as missing by the cache.
     */
    public function testCachedFalseValueIsNotMissing():void
    {
        var key:String = "a false item";
        var value:Boolean = false;
        cache.set(key, value);
        Assert.assertEquals(false, cache.get(key));
        Assert.assertEquals(DeleteStatus.DELETE_SUCCESSFUL, cache.deleteItem(key));
    }

    [Test(description="Test items from cache are not defined after delete.")]

    /**
     *  Test items from cache are not defined after delete.
     */
    public function testDelteItemRemovesItem():void
    {
        var key:String = "key";
        var value:String = "value";
        cache.set(key, value);
        cache.deleteItem(key);
        Assert.assertEquals(null, cache.get(key));
    }

     [Test(description="Tests that an item added is then available from the cache.")]

    /**
     *  Tests that an item added is then available from the cache.
     */
    public function testAddItem():void
    {
        var key:String = "key";
        var value:String = "value";
        cache.add(key, value);
        Assert.assertEquals(value, cache.get(key));
    }

    [Test(description="Test that items added won't replace already in cache.")]

    /**
     *   Test that items added won't replace already in cache.
     */
    public function testAddDoesntReplace():void
    {
        var key:String = "key";
        var value:String = "value";
        var newValue:String = "new value";
        cache.set(key, value);
        Assert.assertFalse(cache.add(key, newValue));
        Assert.assertEquals(value, cache.get(key));
    }

    [Test(description="Test that replace doesn't create a new item.")]

    /**
     *  Test that replace doesn't create a new item.
     */
    public function testReplaceDoesntCreateANewItem():void
    {
        var key:String = "new key";
        var value:String = "new value";
        Assert.assertFalse(cache.replace(key, value));
        Assert.assertEquals(null, cache.get(key));
    }

    [Test(description="Test that replace does replace an item in the cache if it already exists.") ]

    /**
     *  Test that replace does replace an item in the cache if it already
     *  exists.
     */
    public function testReplaceItemReplacesItem():void
    {
        var key:String = "key";
        var value:String = "first value";
        var newValue:String = "new value";
        cache.set(key, value);
        Assert.assertTrue(
            "Cache replace must accept a value change.",
            cache.replace(key, newValue)
        );
        Assert.assertEquals(newValue, cache.get(key));
    }

}
}
